package com.colud.client.test;

import com.colud.client.handler.CliBusiHandler;
import com.colud.client.handler.Decoder;
import com.colud.client.handler.Encoder;
import com.colud.client.handler.HeartBeatHandler;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.*;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.handler.logging.LoggingHandler;
import org.jboss.netty.handler.timeout.IdleStateHandler;
import org.jboss.netty.logging.InternalLogLevel;
import org.jboss.netty.util.HashedWheelTimer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;


/**
 * @author netty 客户端连接
 */
public class JT809Client {
    private Logger log = LoggerFactory.getLogger(getClass());

    private long connectTimeoutMillis = 3000;

    private boolean tcpNoDelay = false;

    private boolean reuseAddress = true;

    private boolean keepAlive = true;

    private int workerCount = 4;

    private ClientBootstrap bootstrap = null;

    private static Channel channel = null;

    private Executor bossExecutor = Executors.newCachedThreadPool();

    private Executor workerExecutor = Executors.newCachedThreadPool();

    public JT809Client() {
        init();
    }

    public void init() {

        bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(
                bossExecutor, workerExecutor, workerCount));
        bootstrap.setOption("tcpNoDelay", tcpNoDelay);
        bootstrap.setOption("connectTimeoutMillis", connectTimeoutMillis);
        bootstrap.setOption("reuseAddress", reuseAddress);
        bootstrap.setOption("keepAlive", keepAlive);
    }

    public Channel getChannel(String address, int port) {

        if (null == channel || !channel.isOpen()) {
            bootstrap.setOption("writeBufferHighWaterMark", 64 * 1024);
            bootstrap.setOption("writeBufferLowWaterMark", 32 * 1024);
            bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
                @Override
                public ChannelPipeline getPipeline() throws Exception {
                    ChannelPipeline pipeline = Channels.pipeline();
                    pipeline.addLast("logging", new LoggingHandler(InternalLogLevel.INFO));
                    pipeline.addLast("timeout", new IdleStateHandler(new HashedWheelTimer(), 10, 60, 0));//设置空闲心跳机制
                    pipeline.addLast("heartbeat", new HeartBeatHandler());//心跳发送包处理handler
                    pipeline.addLast("decode", new Decoder(""));//解码
                    pipeline.addLast("encoder", new Encoder());//编码
                    pipeline.addLast("cliBusiHandler", new CliBusiHandler());//反馈数据处理
                    return pipeline;
                }
            });
            ChannelFuture future = bootstrap.connect(new InetSocketAddress(
                    address, port));
            future.awaitUninterruptibly();
            if (future.isSuccess()) {
                log.info("jt809 client connect success-------send");
                channel = future.getChannel();
            } else {
                //throw new RuntimeException(future.getCause());
            }
        }
        return channel;
    }

}
